import React, {
  Component,
  createRef,
  createContext,
  useRef,
  useState,
} from "react";
import PropType from "prop-types";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import gsap from "gsap"; //动画库
import Stats from "stats.js"; //性能监控
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js"; // FBX 模型加载器
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'; //EffectComposer 效果组合器 它是处理 WebGLRenderer 效果的 接收 renderer为参数
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass'; // RenderPass 处理通道 它是处理 scene 场景和相机 camera 的。 接收 scene camera 为参数
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass';//UnrealBloomPass 泛光通道
import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js'; //添加抗锯齿的效果
import { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass'; // 高亮发光描边通道 OutlinePass(画布宽高二维向量，场景scene,相机camera)
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; //模型加载器
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; //模型解压缩

const windowWidth =   window.innerWidth
const windowHeigth = window.innerHeight

const dracoLoader = new DRACOLoader(); //模型解压缩
const loader = new GLTFLoader(); //gltf模型加载器
const scene = new THREE.Scene(); // 场景
const camera = new THREE.PerspectiveCamera(
  85,
  windowWidth / windowHeigth,
  1,
  1200
); // 相机



const renderer = new THREE.WebGLRenderer({antialias:true}); //渲染器 antialias扛锯齿 默认为false
const controls = new OrbitControls(camera, renderer.domElement); // 轨道控制器

const outlinePass = new OutlinePass(new THREE.Vector2(windowWidth,windowHeigth), scene, camera);
const axesHelper = new THREE.AxesHelper(50); // 辅助线
scene.add(axesHelper);



const raycaster = new THREE.Raycaster(); //光线投射Raycaster
window.addEventListener('click',function(event){
  outlinePass.selectedObjects = [];
  let x=( event.clientX /windowWidth ) * 2 - 1;
  let y  = - ( event.clientY /windowHeigth) * 2 + 1;
  // 通过摄像机和鼠标位置更新射线
  raycaster.setFromCamera( new THREE.Vector2(x,y), camera );
  // 计算物体和射线的焦点
	const intersects = raycaster.intersectObjects( scene.children );
  if(intersects && intersects.length !==0){
    
    outlinePass.selectedObjects = [intersects[0].object];  //6、设置需要高亮发光描边的模型对象
  } 

})

const Home = () => {

  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);


  const light = new THREE.AmbientLight( 0x404040 ); // soft white light
  scene.add( light );
  const directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );
  scene.add( directionalLight );
  camera.position.x = 150;
  camera.position.y = 150;
  camera.position.z = 150;

  dracoLoader.setDecoderPath('./draco');
  loader.setDRACOLoader(dracoLoader);



  // 1、创建后处理对象EffectComposer，WebGL渲染器作为参数
  const composer = new EffectComposer(renderer);
  // 2、创建一个渲染器通道，场景和相机作为参数
  const renderPass = new RenderPass(scene, camera);
  // 3、设置renderPass通道
  composer.addPass(renderPass);
  // 4、创建OutlinePass通道,显示模型外轮廓边框
  // const v2 = new THREE.Vector2(windowWidth, windowHeigth);
  // 5、outlinePass第一个参数v2的尺寸和canvas画布保持一致
  // const outlinePass = new OutlinePass(v2, scene, camera);
  //高亮发光描边外观样式设置
  outlinePass.visibleEdgeColor.set(0xffff00); //模型描边颜色，默认白色 
  outlinePass.edgeThickness = 4; //高亮发光描边厚度
  outlinePass.edgeStrength = 6; //高亮描边发光强度
  outlinePass.pulsePeriod = 2; //模型闪烁频率控制，默认0不闪烁
  

  // 7、设置OutlinePass通道

  loader.load( '3D/model (1).glb' , function ( object ) {

    scene.add( object.scene );
   

 

  } );

  composer.addPass(outlinePass);
  // 去掉锯齿
  const FXAAShaderPass = new ShaderPass(FXAAShader);
  FXAAShaderPass.uniforms['resolution'].value.set(1 / windowWidth, 1 / windowHeigth);
  FXAAShaderPass.renderToScreen = true;
  composer.addPass(FXAAShaderPass);


 
  function animate() {
  
    requestAnimationFrame(animate);
   
    controls.update();
    // renderer.render(scene, camera); 使用发光通道之后，这个就不能在用了
    // 8、使用后处理模块EffectComposer，可通过该对象的render方法调用渲染器的render方法
    composer.render();
  }
  animate();
  return <div></div>;
};

export default Home;
